﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Diagnostics.Contracts;

using System.Xml;

namespace SimpleIR
{
	/// <summary>
	/// This class is an abstract base class for all the regions in out T1T2 basic block construction.
	/// </summary>
	public abstract class IRT1T2Region
	{
		/// <summary>
		/// Number the stmts and flow structures in the region.
		/// </summary>
		public abstract void NumberRegion(CtrGen cg);

		/// <summary>
		/// Get the min statement number appearing in the region.
		/// </summary>
		public abstract int MinStmt();

		/// <summary>
		/// Get the max statement number appearing in the region (or the region id if it is the largest).
		/// </summary>
		public abstract int MaxStmt();

		/// <summary>
		/// Load this call graph chunk for display as a dgml graph.
		/// </summary>
		public abstract void DGMLDisplayString(XmlWriter xwn, XmlWriter xwl, bool toplevel);

		/// <summary>
		/// Generate the unique dgml name for this node.
		/// </summary>
		public abstract string GenDisplayNameString();

		/// <summary>
		/// Identify loads where the local variable is dead after the load
		/// </summary>
		/// <param name="liveatexit">Vars that are live at block exit.</param>
		/// <param name="addrtakenvars">Set of all vars that have their addresses taken.</param>
		internal abstract void PropLiveVariables(Dictionary<long, HashSet<IRVarName>> liveatexit, HashSet<IRVarName> addrtakenvars);

		/// <summary>
		/// Compute the eval stack expression values for the region.
		/// </summary>
		internal abstract void ComputeEvalStackExpressions(Dictionary<long, SymbolicEvalStack> evsts, IRProgram p);

		/// <summary>
		/// Do loop copy analysis to build before/current/after/any info for use in later analysis.
		/// </summary>
		/// <param name="evsts">State of eval stack at component entry.</param>
		/// <param name="p">The program.</param>
		/// <param name="iterok">True if we are currently ok for identifying a loop get iterator.</param>
		/// <param name="iterator">The name of the iterator.</param>
		/// <param name="itergets">Calls to the "Current" method for this iterator.</param>
		/// <param name="hasadvance">True if we found a suitable enumerator advance</param>
		/// <param name="indexok">True if we are currently ok for identifying a loop get index pair.</param>
		/// <param name="indexvar">The name of the index container.</param>
		/// <param name="optfield">Optional member field that container is reached from.</param>
		/// <param name="indexgets">Calls to the load operation.</param>
		/// <param name="indexpos">The position variable that is used in the loads.</param>
		/// <param name="indexstore">Where the indexpos indexed value is stored.</param>
		internal abstract void DoLoopCopyAnalysis(bool findnewactions, long headblockid, long uniquebackblockid, IRProgram p,
			ref bool iterok, ref IRVarName iterator, HashSet<IRCallOp> itergets, ref IRCallOp enumadv,
			ref bool indexok, ref IRVarName indexvar, ref IRMemberField optfield, HashSet<IRByteCode> indexgets,
			ref IRVarName indexpos, ref IRStoreFromEvalStackBasic indexstore, Dictionary<long, IRBasicBlock> idtobbmap);
	}
}
